/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Controlador.Service.Ventas;

import Controlador.Bean.Almacen.Almacen;
import Controlador.Bean.Almacen.ProductosEnAlmacen;
import Controlador.Bean.Almacen.ProdxSolicitudMovimiento;
import Controlador.Bean.Almacen.SolicitudMovimiento;
import Controlador.Bean.Ventas.Cliente;
import Controlador.Bean.Ventas.ClienteBusqueda;
import Controlador.Bean.Ventas.Departamento;
import Controlador.Bean.Ventas.Provincia;
import Controlador.Bean.Ventas.Distrito;
import Controlador.Bean.Ventas.LineaCotizacion;
import Controlador.Bean.Ventas.ProdBusqueda;
import Controlador.Bean.Ventas.Cotizacion;
import Controlador.Bean.Ventas.CotizacionBusqueda;
import Controlador.Bean.Ventas.Pedido;
import Controlador.Bean.Ventas.PedidoBusqueda;
import Controlador.Bean.Ventas.LineaPlan;
import Controlador.Bean.Ventas.PlanVentas;
import Controlador.Bean.Ventas.Facturacion;
import Controlador.Bean.Ventas.FacturacionBusqueda;
import Controlador.Bean.Ventas.LineaDevolucion;
import Controlador.Bean.Ventas.Devolucion;
import Controlador.Bean.Ventas.NotaCredito;
import Controlador.Bean.Ventas.DevolucionBusqueda;
import Controlador.Bean.Ventas.NotaCreditoBusqueda;
import Controlador.Service.Almacen.GestionAlmacenes;
import gui.General.Main;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.JProgressBar;

/**
 *
 * @author Luis Enrique
 */
public class GestionVentas {
    
    private GestionVentas() {};
    
    static private GestionVentas VentasGestion=null; 
		   
    public static GestionVentas getInstance(){    
        if(VentasGestion==null) VentasGestion= new GestionVentas();
        return VentasGestion;
    }
    
    //CLIENTE
    
    public static void agregarClientesMasivo(File file, JProgressBar ProgressBar){
        ServicioCliente scliente= ServicioCliente.getInstance();
        scliente.agregarClientesMasivo(file, ProgressBar);
    }
    
    public static void agregarCliente(Cliente cliente){
        ServicioCliente scliente= ServicioCliente.getInstance();
        scliente.agregarCliente(cliente);
    }
    
    public void modificarCliente(Cliente cliente){
        ServicioCliente scliente= ServicioCliente.getInstance();
        scliente.modificarCliente(cliente);
    }
    
    public Cliente consultarCliente(String codCliente){
        Cliente cliente = ServicioCliente.getInstance().getCliente(codCliente);
        return cliente;
    }
    
    public ArrayList<Cliente> queryAllClientes (){
        ArrayList<Cliente> clientes = ServicioCliente.getInstance().seleccionarAllClientes();
        return clientes;        
    }
    
    public ArrayList<Cliente> queryClientes (ClienteBusqueda clienteBusqueda){
        ArrayList<Cliente> clientes = ServicioCliente.getInstance().seleccionarClientes(clienteBusqueda);
        return clientes;        
    }
    
    public boolean eliminarCliente (String idCliente){
        boolean flag = consultaClienteDelete(idCliente);
        if(flag){
            ServicioCliente.getInstance().eliminarCliente(idCliente);
            return flag;
        }
        else
            return flag;
    }
    
    public boolean consultaClienteDelete(String codCliente){
        boolean flag = ServicioCliente.getInstance().consultaClienteDelete(codCliente);
        return flag;
    }   
    
    //DEPARTAMENTO
    
    public ArrayList<Departamento> consultarDepartamento(){
        ArrayList<Departamento> departamentos =ServicioUbigeo.getInstance().getDepartamentos();      
        return departamentos;
    }
    
    public String obtenerDepartamento(String idProvincia){
        String idDepartamento = ServicioUbigeo.getInstance().getIdDepartamento(idProvincia);
        return idDepartamento;
    }
    
    //PROVINCIA
    
    public ArrayList<Provincia> consultarProvincia(String idDepartamento){
        ArrayList<Provincia> provincias =ServicioUbigeo.getInstance().getProvincias(idDepartamento);
        return provincias;
    }
    
    public String obtenerProvincia(String idDistrito){
        String idProvincia = ServicioUbigeo.getInstance().getIdProvincia(idDistrito);
        return idProvincia;
    }
    
    //DISTRITO
    
    public ArrayList<Distrito> consultarDistrito(String idProvincia){
        ArrayList<Distrito> distritos =ServicioUbigeo.getInstance().getDistritos(idProvincia);
        return distritos;
    }
    
    //COTIZACION
    
    public String getCodCotizacion(){
        String codigo = ServicioCotizacion.getInstance().getCodCotizacion();
        return codigo;
    }
    
    public int getCorrelativoCotizacion(){
        int correlativo = ServicioCotizacion.getInstance().getCorrelativoCotizacion();
        return correlativo;
    }
    
    public ArrayList<ProdBusqueda> queryAllProd(ProdBusqueda prodBusqueda){
        ArrayList<ProdBusqueda> productos =ServicioCotizacion.getInstance().getProductosBusqueda(prodBusqueda);
        return productos;
    }
    
    public void registrarCotizacion(Cotizacion cot,ArrayList<LineaCotizacion> lineas){
        ServicioCotizacion scotizacion= ServicioCotizacion.getInstance();
        scotizacion.registrarCotizacion(cot);
        scotizacion.registrarLineaCotizacion(lineas,cot.getIdCotizacion());
    }
    
    public ArrayList<CotizacionBusqueda> queryAllCotizacion(){
        ArrayList<CotizacionBusqueda> cotizaciones = ServicioCotizacion.getInstance().seleccionarAllCotizaciones();
        return cotizaciones;
    }
    
    public ArrayList<CotizacionBusqueda> queryCotizacion (CotizacionBusqueda cotizacionBusqueda){
        ArrayList<CotizacionBusqueda> cotizaciones = ServicioCotizacion.getInstance().seleccionarCotizaciones(cotizacionBusqueda);
        return cotizaciones;        
    }
    
    public void anularCotizacion (String idCotizacion){
        ServicioCotizacion.getInstance().eliminarCotizacion(idCotizacion);
    }
    
    public ArrayList<LineaCotizacion> consultarLineasCotizacion(String idCotizacion){
        ArrayList<LineaCotizacion> lineas = ServicioCotizacion.getInstance().seleccionarLineasCotizacion(idCotizacion);
        return lineas;
    }
    
    public void actualizarCotizacionesVencidas (){
        Date fecha = new Date();
        ServicioCotizacion.getInstance().actualizarCotizacionesVencidas(fecha);
    }
    
    //PEDIDO
    
    public String getCodPedido(){
        String codigo = ServicioPedido.getInstance().getCodPedido();
        return codigo;
    }
    
    public int getCorrelativoPedido(){
        int correlativo = ServicioPedido.getInstance().getCorrelativoPedido();
        return correlativo;
    }
    
    public void registrarPedido(Pedido pedido){
        ServicioPedido spedido = ServicioPedido.getInstance();
        spedido.registrarPedido(pedido);
        ServicioCotizacion scotizacion = ServicioCotizacion.getInstance();
        scotizacion.actualizarCotizacionPed(pedido.getIdCotizacion());
    }
       
    public ArrayList<PedidoBusqueda> queryAllPedidos(){
        ArrayList<PedidoBusqueda> pedidos = ServicioPedido.getInstance().seleccionarAllPedidos();
        return pedidos;
    }
    
    public ArrayList<PedidoBusqueda> queryPedidos (PedidoBusqueda pedidoBusqueda){
        ArrayList<PedidoBusqueda> pedidos = ServicioPedido.getInstance().seleccionarPedidos(pedidoBusqueda);
        return pedidos;        
    }
    
    public void anularPedido (String idPedido){
        ServicioPedido.getInstance().eliminarPedido(idPedido);
        ServicioCotizacion.getInstance().actualizarCotizacionReg(idPedido);
    }
    
    //PLAN DE VENTAS
    
    public String getCodPlanVentas(){
        String codigo = ServicioPlanVentas.getInstance().getCodPlanVentas();
        return codigo;
    }
    
    public int getCorrelativoPlanVentas(){
        int correlativo = ServicioPlanVentas.getInstance().getCorrelativoPlanVentas();
        return correlativo;
    }    
    
    public ArrayList<LineaPlan> queryProdPlan(){
        ArrayList<LineaPlan> lineas = ServicioPlanVentas.getInstance().seleccionarProdPlan();
        return lineas;
    }
 
    public ArrayList<LineaPlan> queryProdPlan2(){
        ArrayList<LineaPlan> lineas = ServicioPlanVentas.getInstance().seleccionarProdPlan2();
        return lineas;
    }
    
    public void registrarPlanVentas(PlanVentas plan,ArrayList<LineaPlan> lineas){
        ServicioPlanVentas splan= ServicioPlanVentas.getInstance();
        splan.registrarPlanVentas(plan);
        splan.registrarLineaPlan(lineas,plan.getIdPlanVentas());
    }
    
    public void anularPlanVentas (String idPlanVentas){
        ServicioPlanVentas.getInstance().eliminarPlanVentas(idPlanVentas);
    }    
    
    public ArrayList<PlanVentas> queryAllPlanes(){
        ArrayList<PlanVentas> planes = ServicioPlanVentas.getInstance().seleccionarAllPlanes();
        return planes;
    }    
    
    public ArrayList<PlanVentas> queryPlanes(PlanVentas planVentas){
        ArrayList<PlanVentas> planes = ServicioPlanVentas.getInstance().seleccionarPlanes(planVentas);
        return planes;
    }
    
    public ArrayList<LineaPlan> consultarLineasPlan (String idPlanVentas){
        ArrayList<LineaPlan> lineas = ServicioPlanVentas.getInstance().seleccionarLineasPlan(idPlanVentas);
        return lineas;
    }
    
    public void actualizarPlanVentasEstado(String codigo){
        ServicioPlanVentas.getInstance().actualizarPlanVentasEstado(codigo);
    }
    
    public Date getFechaPlanVentas(){
        Date fecha = ServicioPlanVentas.getInstance().getFechaPlanVentas();
        return fecha;
    }
            
    //FACTURACION
                   
    public void registrarFacturacion(Facturacion facturacion,String codCotizacion){
        ServicioFacturacion sfacturacion = ServicioFacturacion.getInstance();
        String codigo = sfacturacion.getCodFacturacion(facturacion);
        facturacion.setIdFactura(codigo);
        sfacturacion.registrarFacturacion(facturacion);
        ServicioCotizacion.getInstance().actualizarCotizacionFac(codCotizacion);
        ServicioPedido.getInstance().actualizarPedidoFac(facturacion.getIdPedido());
    }
    
    public ArrayList<FacturacionBusqueda> queryAllDocumentos(){
        ArrayList<FacturacionBusqueda> documentos = ServicioFacturacion.getInstance().seleccionarAllDocs();
        return documentos;
    }
    
    public ArrayList<FacturacionBusqueda> queryDocs(FacturacionBusqueda docs){
        ArrayList<FacturacionBusqueda> documentos = ServicioFacturacion.getInstance().seleccionarDocs(docs);
        return documentos;
    }
    
    public ArrayList<LineaCotizacion> llenaLineas(String codigo){
        String codCotizacion = ServicioFacturacion.getInstance().getCodCotizacion(codigo);
        ArrayList<LineaCotizacion> lineas = consultarLineasCotizacion(codCotizacion);
        return lineas;
    }
    
    //DEVOLUCION

    public String getCodDevolucion(){
        String codigo = ServicioDevolucion.getInstance().getCodDevolucion();
        return codigo;
    }
    
    public ArrayList<LineaDevolucion> llenaLineasDev(String codigo){
        ArrayList<LineaDevolucion> lineasDev = new ArrayList<>();
        String codCotizacion = ServicioFacturacion.getInstance().getCodCotizacion(codigo);
        ArrayList<LineaCotizacion> lineas = consultarLineasCotizacion(codCotizacion);
        for(int i=0;i<lineas.size();i++){
            LineaCotizacion cot = lineas.get(i);
            LineaDevolucion tmp = new LineaDevolucion(cot.getIdProducto(),cot.getNumLinea(),cot.getNombre(),cot.getPrecioUnitario(),cot.getCantidad(),0,cot.getSubTotal());
            lineasDev.add(tmp);
        }
        return lineasDev;
    }
    
    public void registrarDevolucion(Devolucion dev,ArrayList<LineaDevolucion> lineas){
        ServicioDevolucion.getInstance().registrarDevolucion(dev);
        ServicioDevolucion.getInstance().registrarLineaDevolucion(lineas,dev.getIdDevolucion());   
    }
    
    public ArrayList<FacturacionBusqueda> queryAllDocumentosFact(){
        ArrayList<FacturacionBusqueda> documentos = ServicioFacturacion.getInstance().seleccionarAllDocsFact();
        return documentos;
    }
    
    public ArrayList<FacturacionBusqueda> queryDocsFact(FacturacionBusqueda docs){
        ArrayList<FacturacionBusqueda> documentos = ServicioFacturacion.getInstance().seleccionarDocsFact(docs);
        return documentos;
    }
    
    public ArrayList<DevolucionBusqueda> queryAllDevoluciones(){
        ArrayList<DevolucionBusqueda> documentos = ServicioDevolucion.getInstance().seleccionarAllDevs();
        return documentos;
    }
    
    public ArrayList<DevolucionBusqueda> queryDevs(DevolucionBusqueda devs){
        ArrayList<DevolucionBusqueda> documentos = ServicioDevolucion.getInstance().seleccionarDevs(devs);
        return documentos;
    }
    
    public ArrayList<LineaDevolucion> seleccionarLineasDev(String codigo){
        ArrayList<LineaDevolucion> lineas = ServicioDevolucion.getInstance().seleccionarLineasDev(codigo);
        return lineas;
    }
            
    // NOTA DE CREDITO
    
    public String getCodNotaCredito(){
        String codigo = ServicioNotaCredito.getInstance().getCodNotaCredito();
        return codigo;
    }
    
    public void registrarNC(NotaCredito nc){
        ServicioNotaCredito.getInstance().registrarNotaCredito(nc);
    }
    
    public NotaCreditoBusqueda getNotaCredito(String codigo){
        NotaCreditoBusqueda ncb = ServicioNotaCredito.getInstance().getNotaCredito(codigo);
        return ncb;
    }
             
    public ArrayList<NotaCreditoBusqueda> queryNC(NotaCreditoBusqueda ncs){
        ArrayList<NotaCreditoBusqueda> documentos = ServicioNotaCredito.getInstance().seleccionarNCs(ncs);
        return documentos;
    }
    
    public void actualizarNCEstado(String codigo){
        ServicioNotaCredito.getInstance().actualizarNCEstado(codigo);
    }
    
    public  static void GenerarSolicitudMovimientoLC(ArrayList<LineaCotizacion> lineacotizacion){
        
        ArrayList<ProductosEnAlmacen> productosenalmacenLinea = new ArrayList();
        ArrayList<ProductosEnAlmacen> productosenalmacen = new ArrayList();
        ArrayList<String> productos = new ArrayList();        
        for(int i = 0; i<lineacotizacion.size(); i++){
            ProductosEnAlmacen pea = new ProductosEnAlmacen("",lineacotizacion.get(i).getIdProducto(),lineacotizacion.get(i).getCantidad());
            productosenalmacenLinea.add(pea);
            productos.add(lineacotizacion.get(i).getIdProducto());
        }
        productosenalmacen =  Controlador.Service.Almacen.GestionAlmacenes.ListaDeProductosPorAlmacen(productos);
        boolean haySalida = false;
         ArrayList<ProductosEnAlmacen> productosenalmacenFINAL = new ArrayList();       
            for (int j = 0; j<productosenalmacenLinea.size(); j++){
                ProductosEnAlmacen pemLineaaux = productosenalmacenLinea.get(j);
                for(int k=0;k<productosenalmacen.size();k++){
                    ProductosEnAlmacen pemaux = productosenalmacen.get(k);                      
                        if(pemLineaaux.getCantidad() <= pemaux.getCantidad() && 0==pemaux.getIdproductos().compareTo(pemLineaaux.getIdproductos())){                            
                         haySalida = true;
                         ProductosEnAlmacen movimiento = new ProductosEnAlmacen(pemaux.getIdAlmacen(), pemaux.getIdproductos(),pemLineaaux.getCantidad());
                         productosenalmacenFINAL.add(movimiento);
                         productosenalmacenLinea.remove(j);
                         j--;
                         productosenalmacen.get(k).setCantidad(pemaux.getCantidad()-pemLineaaux.getCantidad());
                         if(pemaux.getCantidad()==0) productosenalmacen.remove(k);
                         break;
                        } 
                        else if( pemaux.getCantidad()>0 && 0==pemaux.getIdproductos().compareTo(pemLineaaux.getIdproductos())){
                            haySalida = true;
                            ProductosEnAlmacen movimiento = new ProductosEnAlmacen(pemaux.getIdAlmacen(), pemaux.getIdproductos(),pemaux.getCantidad());
                            productosenalmacenFINAL.add(movimiento);                            
                            productosenalmacenLinea.get(j).setCantidad(pemLineaaux.getCantidad()-pemaux.getCantidad());
                            productosenalmacen.remove(k);
                            k--;
                        }
                }
            }
           if(haySalida){
               SolicitudMovimiento solMov = new SolicitudMovimiento("",Main.usu.getIdEmpleadoAdm(),productosenalmacenFINAL.get(0).getIdAlmacen(),"Salida",new Date(),"Ventas","1","Externo");
               
               String idSolMov=Controlador.Service.Almacen.GestionAlmacenes.agregarSolicitudMovimientoDC(solMov);
               ArrayList<ProdxSolicitudMovimiento> prodxSolMovList= new ArrayList<>();
               String codAlmacen=null;
               int j;
               for(j=0;j<productosenalmacenFINAL.size();j++){
                   if(codAlmacen!=null&&productosenalmacenFINAL.get(j).getIdAlmacen().compareTo(codAlmacen)!=0 ){                       
                       Controlador.Service.Almacen.GestionAlmacenes.agregarProdxSolMov(prodxSolMovList, codAlmacen, "Salida");
                       prodxSolMovList= new ArrayList<>();
                       codAlmacen=productosenalmacenFINAL.get(j).getIdAlmacen();
                       solMov = new SolicitudMovimiento("",Main.usu.getIdEmpleadoAdm(),productosenalmacenFINAL.get(j).getIdAlmacen(),"Salida",new Date(),"Venta","1","Externo");
                       idSolMov=Controlador.Service.Almacen.GestionAlmacenes.agregarSolicitudMovimientoDC(solMov);
                   }
                   if(codAlmacen==null) codAlmacen=productosenalmacenFINAL.get(j).getIdAlmacen();
                  
                   ProdxSolicitudMovimiento prodxSolMov= new ProdxSolicitudMovimiento();
                   prodxSolMov.setCantidad(productosenalmacenFINAL.get(j).getCantidad());
                   prodxSolMov.setIdProducto(productosenalmacenFINAL.get(j).getIdproductos());
                   prodxSolMov.setIdSolicitudMovimiento(idSolMov);
                   prodxSolMovList.add(prodxSolMov);                   
               }
              if(codAlmacen!=null){
                       Controlador.Service.Almacen.GestionAlmacenes.agregarProdxSolMov(prodxSolMovList, codAlmacen, "Salida");
                   }
           }
    }
    
    
    public  static void GenerarSolicitudMovimientoLD(ArrayList<LineaDevolucion> lineaDevolucion){
        
        HashMap<String,Long> DevolucionxProd= new HashMap<>();
        for(int i=0;i<lineaDevolucion.size();i++){
            DevolucionxProd.put(lineaDevolucion.get(i).getIdProducto(),(DevolucionxProd.get(lineaDevolucion.get(i).getIdProducto())==null?0:DevolucionxProd.get(lineaDevolucion.get(i).getIdProducto()))+ lineaDevolucion.get(i).getCantDev());
        }
        if(DevolucionxProd.size()>0){
            List<Almacen> alms=GestionAlmacenes.obtenerAlmacenes();
            String idAlmacen= alms.get(alms.size()-1).getIdAlmacen();
            SolicitudMovimiento solMov = new SolicitudMovimiento("",Main.usu.getIdEmpleadoAdm(),idAlmacen,"Entrada",new Date(),"Devolución","1","Externo");
               String idSolMov=Controlador.Service.Almacen.GestionAlmacenes.agregarSolicitudMovimientoDC(solMov);
               ArrayList<ProdxSolicitudMovimiento> prodxSolMovList= new ArrayList<>();
               Iterator<Map.Entry<String,Long>> it=DevolucionxProd.entrySet().iterator();
               while(it.hasNext()){
                   Map.Entry<String,Long> map=it.next();
                   ProdxSolicitudMovimiento prodxSolMov= new ProdxSolicitudMovimiento();
                   prodxSolMov.setCantidad(map.getValue().doubleValue());
                   prodxSolMov.setIdProducto(map.getKey());
                   prodxSolMov.setIdSolicitudMovimiento(idSolMov);
                   prodxSolMovList.add(prodxSolMov);                                  
               }
               Controlador.Service.Almacen.GestionAlmacenes.agregarProdxSolMov(prodxSolMovList, idAlmacen, "Entrada");
        }
    }
    
    
    //FUNCIONES UTILES
    
    public double Redondear(double numero){
        return Math.rint(numero*100)/100;
    }
    
    public int getdiasVencimiento(){
        return 15; 
    }

    public double getIGV(){
        return 0.18; 
    }
    
    public double getTipoCambio(){
        return 2.57; 
    }
    
    public int getDiasPlanVentas(){
        return 30;
    }
    
    public int getCantMaxPedido(){
        return 1000;
    }
    
    public int getCantMaxPlanVentas(){
        return 1000;
    }
}